home *** CD-ROM | disk | FTP | other *** search
- /* dirutil.c - MS-DOS directory reading routines
- *
- * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
- * Directory sorting by Mike Chepponis, K3MC
- * New version using regs.h by Russell Nelson.
- * Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
- *
- * Added path filter functions and applied to dodir
- * also used by ftpcli.c, added current directory
- * storage capability (11/92 WA3DSP)
- * Bugfixes in the above by WG7J
- */
-
- #include "global.h"
- #include "ctype.h"
- #include "commands.h"
- #include "hardware.h"
- #include <sys/stat.h>
-
- #ifndef UNIX
- # ifndef S_ISDIR
- # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- # endif
- #else
- # ifdef HAVE_SYS_STATFS_H
- # include <sys/statfs.h>
- # define f_bavail f_bfree
- # else
- # if defined(HAVE_SYS_PARAM_H) && !defined(_lint)
- # include <sys/param.h>
- # endif
- # if defined(HAVE_SYS_MOUNT_H) && !defined(_lint)
- # include <sys/mount.h>
- # endif
- # ifdef HAVE_SYS_VFS_H
- # include <sys/vfs.h>
- # endif
- # endif
- #endif /* UNIX */
-
- #ifndef _lint
- #include <time.h>
- #endif
- #if !defined (_lint) || !defined(MSDOS)
- #include "proc.h"
- #include "session.h"
- #endif
- #include "smtp.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: dirutil.c,v 1.33 1997/09/14 14:37:46 root Exp root $";
- #endif
-
-
- #ifdef CALLSERVER
- #include <string.h>
- #include <alloc.h>
- extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:" */
- #endif
-
-
- struct dirsort {
- struct dirsort *next;
- struct ffblk de;
- };
-
-
- #define NULLSORT (struct dirsort *)0
-
- static int nextname (int command, const char *name, struct ffblk * sbuf);
- static int dircmd (int argc,char *argv[],void *p);
- static char const *wildcardize (char const *path);
- static void commas (char *dest);
- static int fncmp (char *a, char *b);
- static void format_fname_full (FILE * file, struct ffblk * sbuf, int full, int n, const char *path);
- static void free_clist (struct dirsort * this);
- static void print_free_space (const char *path, FILE * file, int n);
- char *defpath (struct cur_dirs * curdirs, char *path);
- extern void crunch (char *buf, const char *path);
-
- #ifdef TNOS_68K
- #define REGFILE (FA_DIREC)
- #define ALLFILES "*"
- #include <modes.h>
- #else
- #define REGFILE (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
- #ifdef UNIX
- #define ALLFILES "*"
- #else
- #define ALLFILES "*.*"
- #endif
- #endif
-
- #define insert_ptr(list,new) (new->next = list,list = new)
-
-
-
- /* Create a directory listing in a temp file and return the resulting file
- * descriptor. If full == 1, give a full listing; else return just a list
- * of names.
- */
- FILE *
- dir (char *path, int full)
- {
- FILE *fp;
- char *path1;
- char *path2;
-
- if ((fp = tmpfile ()) != NULLFILE) {
- path1 = strdup ((!path) ? Command->curdirs->dir : path);
- if (full == 1)
- fprintf (fp, "Directory of %s at %s\n\n", path1, Hostname);
- path2 = strdup (make_dir_path (2, path1, Command->curdirs->dir));
- (void) getdir (path2, full, fp);
- free (path1);
- free (path2);
- rewind (fp);
- }
- return fp;
- }
-
-
-
- /* find the first or next file and lowercase it. */
- static int
- nextname (int command, const char *name, struct ffblk *sbuf)
- {
- int found;
-
- switch (command) {
- case 0:
- found = findfirst (name, sbuf, REGFILE);
- break;
- default:
- found = findnext (sbuf);
- }
- found = (found == 0);
- #ifndef UNIX
- if (found)
- (void) strlwr (sbuf->ff_name);
- #endif
-
- return found;
- }
-
-
-
- /* wildcard filename lookup */
- int
- filedir (const char *name, int times, char *ret_str)
- {
- static struct ffblk sbuf;
- int rval;
-
- switch (times) {
- case 0:
- rval = findfirst (name, &sbuf, REGFILE);
- break;
- default:
- rval = findnext (&sbuf);
- break;
- }
- if (rval != 0)
- ret_str[0] = '\0';
- else /* Copy result to output */
- strcpy (ret_str, sbuf.ff_name);
- return rval;
- }
-
-
-
- /* do a directory list to the stream
- * full = 0 -> short form, 1 is long, 2 is long with "|" down center, and
- * -1 is short with two entries per line.
- */
- int
- getdir (char const *path, int full, FILE *file)
- {
- struct ffblk sbuf;
- int command = 0;
- int n = 0;
- struct dirsort *head, *here, *new;
-
- path = wildcardize (path);
- head = NULLSORT; /* No head of chain yet... */
- for (;;) {
- kwait (NULL);
- if (!nextname (command, path, &sbuf))
- break;
- command = 1; /* Got first one already... */
- #ifdef MSDOS
- if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
- continue;
- #endif
-
- new = (struct dirsort *) mallocw (sizeof (struct dirsort));
-
- new->de = sbuf; /* Copy contents of directory entry struct */
-
- /* insert it into the list */
- if (!head || fncmp (new->de.ff_name, head->de.ff_name) < 0)
- insert_ptr (head, new);
- else {
- register struct dirsort *this;
-
- for (this = head; this->next != NULLSORT; this = this->next)
- if (fncmp (new->de.ff_name, this->next->de.ff_name) < 0)
- break;
- insert_ptr (this->next, new);
- }
- } /* infinite FOR loop */
-
- for (here = head; here; here = here->next)
- format_fname_full (file, &here->de, full, ++n, path);
-
- /* Give back all the memory we temporarily needed... */
- free_clist (head);
-
- if (full == 1)
- print_free_space (path, file, n);
-
- if ((full == -1) && (n & 1))
- fputs ("\n", file);
-
- return 0;
- }
-
-
-
- static int
- fncmp (register char *a, register char *b)
- {
- int i;
-
- for (;;) {
- #ifdef MSDOS
- if (*a == '.')
- return -1;
- if (*b == '.')
- return 1;
- #endif
- if ((i = *a - *b++) != 0)
- return i;
- if (!*a++)
- return -1;
- }
- }
-
-
-
- #ifdef ALLCMD
- /* Change working directory */
- int
- docd (int argc, char *argv[], void *p OPTIONAL)
- {
- if (argc > 1) {
- if (!dir_ok (argv[1], Command->curdirs)) {
- tprintf ("Invalid Drive/Directory - %s\n", argv[1]);
- return 1;
- }
- }
- tprintf ("Local Directory - %s\n", Command->curdirs->dir);
- return 0;
- }
-
-
-
- #ifdef MSDOS
- /* Change working drive */
- int
- dodrive (int argc, char *argv[], void *p)
- {
- char **margv;
-
- margv = (char **) callocw (2, sizeof (char *));
-
- margv[1] = strdup (argv[0]);
- (void) docd (2, margv, p);
- free (margv[1]);
- free (margv);
- return 0;
- }
-
- #endif /* MSDOS*/
- #endif /* ALLCMD */
-
-
-
- char *
- defpath (struct cur_dirs *curdirs OPTIONAL, char *path)
- {
- #ifdef MSDOS
- int drive;
-
- drive = tolower (path[0]) - '`';
- if (strlen (path) == 2 && path[1] == ':' && curdirs->curdir[drive] != NULLCHAR)
- return curdirs->curdir[drive];
- else
- #endif
- return path;
- }
-
-
-
- #if (defined(ALLCMD) || defined(ALLSESSIONS))
- /* List directory to console */
- static int
- dircmd (int argc, char *argv[], void *p)
- {
- char *path, *file;
- FILE *fp;
- char tmpname[80];
- char **margv;
-
- if (argc > 1) {
- file = strdup (make_fname (Command->curdirs->dir, defpath (Command->curdirs, argv[1])));
- path = strdup (make_dir_path (argc, file, Command->curdirs->dir));
- free (file);
- } else
- path = strdup (Command->curdirs->dir);
- margv = (char **) callocw (2, sizeof (char *));
-
- (void) tmpnam (tmpname);
- fp = fopen (tmpname, WRITE_TEXT);
- if (fp) {
- (void) getdir (path, 1, fp);
- free (path);
- (void) fclose (fp);
- }
- margv[1] = strdup (tmpname);
- (void) morecmd (2, margv, p);
- free (margv[1]);
- free (margv);
- unlink (tmpname);
- return 0;
- }
-
-
-
- int
- dodir (int argc, char *argv[], void *p)
- {
- char **pargv;
- int i;
-
- if (Curproc->input == Command->input) {
- /* Make private copy of argv and args,
- * spawn off subprocess and return.
- */
- pargv = (char **) callocw ((unsigned) argc + 1, sizeof (char *));
-
- for (i = 0; i < argc; i++)
- pargv[i] = strdup (argv[i]);
- pargv[i] = NULL;
- (void) newproc ("dir", 512, (void (*)(int, void *, void *)) dircmd, argc, (void *) pargv, p, 1);
- } else
- (void) dircmd (argc, argv, p);
- return 0;
- }
-
- #endif /* ALLCMD || ALLSESSIONS */
-
-
-
- #ifdef ALLCMD
- /* Create directory */
- int
- domkd (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
- {
- char path[128];
-
- strncpy (path, make_fname (Command->curdirs->dir, argv[1]), 128);
-
- if (mkdir (path, 0777) == -1)
- tprintf ("Can't make %s: %s\n", path, SYS_ERRLIST(errno));
- return 0;
- }
-
-
-
- /* Remove directory */
- int
- dormd (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
- {
- char path[128];
-
- strncpy (path, make_fname (Command->curdirs->dir, argv[1]), 128);
- if (rmdir (path) == -1)
- tprintf ("Can't remove %s: %s\n", path, SYS_ERRLIST(errno));
- return 0;
- }
-
- #endif /*ALLCMD*/
-
-
-
- /*
- * Return a string with commas every 3 positions.
- * the original string is replace with the string with commas.
- *
- * The caller must be sure that there is enough room for the resultant
- * string.
- *
- *
- * k3mc 4 Dec 87
- */
- static void
- commas (char *dest)
- {
- char *src, *core; /* Place holder for malloc */
- unsigned cc; /* The comma counter */
- unsigned len;
-
- if (!dest)
- return;
- len = strlen (dest);
- /* Make a copy, so we can muck around */
- core = src = strdup (dest);
-
- cc = (len - 1) % 3 + 1; /* Tells us when to insert a comma */
-
- while (*src != '\0') {
- *dest++ = *src++;
- if (((--cc) == 0) && *src) {
- *dest++ = ',';
- cc = 3;
- }
- }
- free (core);
- *dest = '\0';
- }
-
-
-
- /* fix up the filename so that it contains the proper wildcard set */
- static char const *
- wildcardize (char const *path)
- {
- #ifndef TNOS_68K
- #define THISSIZE 64
- #else
- #ifdef UNIX
- #define THISSIZE 1024
- #else
- #define THISSIZE 128
- #endif
- #endif
- struct ffblk sbuf;
- static char ourpath[THISSIZE];
-
- /* Root directory is a special case */
- if (path == NULLCHAR || *path == '\0' ||
- strcmp (path, "\\") == 0 || strcmp (path, "/") == 0) {
- #ifdef MSDOS
- path = "\\*.*";
- #else
- path = "/*";
- #endif
- return path;
- }
- #ifdef MSDOS
- /* MSDOS Root directory can also have a drive letter prefix */
- if (isalpha (*path) &&
- (strcmp (path + 1, ":\\") == 0 || strcmp (path + 1, ":/") == 0)) {
- sprintf (ourpath, "%c:/*.*", *path);
- return ourpath;
- }
- #endif
-
- #ifdef CALLSERVER
- if (CDROM != NULLCHAR && strcmp (path, CDROM) == 0) {
- path = (char *) mallocw (7); /* THIS causes a memory leak ! - WG7J */
- sprintf (path, "%s/*.*", CDROM);
- }
- #endif
-
- /* if they gave the name of a subdirectory, append \*.* to it */
- if (
- #ifdef TNOS_68K
- (*path == '/' && !(strchr (path + 1, '/'))) ||
- #endif
- (nextname (0, path, &sbuf) &&
- (sbuf.ff_attrib & FA_DIREC) &&
- !nextname (1, path, &sbuf))) {
-
- /* if there isn't enough room, give up -- it's invalid anyway */
- if (strlen (path) + 4 > (THISSIZE - 1))
- return path;
- strncpy (ourpath, path, THISSIZE - 4);
- #ifndef MSDOS
- strcat (ourpath, "/*");
- #else
- strcat (ourpath, "\\*.*");
- #endif
- return ourpath;
- }
- return path;
- }
-
-
- #if defined(TNOS_68K) || defined(UNIX)
-
- static void
- format_fname_full (FILE *file, struct ffblk *sbuf, int full, int n, const char *path)
- {
- static char line_buf[1025];
- static char cbuf[1025];
- struct stat sb;
- char *symlinkpath = NULLCHAR;
- char *tcbuf;
-
- strncpy (cbuf, sbuf->ff_name, sizeof (sbuf->ff_name));
- if (sbuf->ff_attrib & FA_DIREC)
- strcat (cbuf, "/");
- if (full == 1) {
- /* Long form, give other info too */
- sprintf (line_buf, "%-14s", cbuf);
- if (strlen (cbuf) > 14)
- strcpy (&line_buf[12], "..");
- if (sbuf->ff_attrib & FA_DIREC)
- strcat (line_buf, " "); /* 10 spaces */
- else {
- sprintf (cbuf, "%ld", sbuf->ff_fsize);
- commas (cbuf);
- sprintf (line_buf + strlen (line_buf), "%9s ", cbuf);
- }
- sprintf (line_buf + strlen (line_buf), "%2d:%02d %2d/%02d/%02d%s",
- sbuf->ff_ftime.tm_hour, sbuf->ff_ftime.tm_min,
- sbuf->ff_ftime.tm_mon + 1, sbuf->ff_ftime.tm_mday,
- sbuf->ff_ftime.tm_year,
- (full == 2) ? " | \n" : (n & 1) ? " " : "\n");
- fputs (line_buf, file);
- } else if (full == 2) {
- if (sbuf->ff_attrib & FA_DIREC)
- cbuf[strlen (cbuf) - 1] = 0; /* strip off the '/' */
-
- tcbuf = mallocw (strlen(cbuf) + strlen(path) + 2);
- strcpy (tcbuf, path);
- if (tcbuf[strlen(tcbuf) - 1] == '*')
- tcbuf[strlen(tcbuf) - 1] = 0;
- strcat (tcbuf, cbuf);
- (void) lstat (tcbuf, &sb);
- if (S_ISLNK(sb.st_mode)) {
- symlinkpath = callocw (1024, 1);
- if (readlink (tcbuf, symlinkpath, 1024) < 0) {
- free (symlinkpath);
- symlinkpath = NULLCHAR;
- }
- }
-
- sprintf (line_buf, "%c%c%c%c%c%c%c%c%c%c 1 tnos tnos %8ld %3.3s %2d %2d:%02d %s%s%s\n",
- (S_ISDIR (sb.st_mode)) ? 'd' : (S_ISLNK (sb.st_mode)) ? 'l' : '-',
- (sb.st_mode & S_IRUSR) ? 'r' : '-',
- (sb.st_mode & S_IWUSR) ? 'w' : '-',
- (sb.st_mode & S_IXUSR) ? 'x' : '-',
- (sb.st_mode & S_IRGRP) ? 'r' : '-',
- (sb.st_mode & S_IWGRP) ? 'w' : '-',
- (sb.st_mode & S_IXGRP) ? 'x' : '-',
- (sb.st_mode & S_IROTH) ? 'r' : '-',
- (sb.st_mode & S_IWOTH) ? 'w' : '-',
- (sb.st_mode & S_IXOTH) ? 'x' : '-',
- sbuf->ff_fsize,
- Months[sbuf->ff_ftime.tm_mon],
- sbuf->ff_ftime.tm_mday,
- sbuf->ff_ftime.tm_hour, sbuf->ff_ftime.tm_min,
- cbuf,
- (symlinkpath != NULLCHAR) ? " -> " : "",
- (symlinkpath != NULLCHAR) ? symlinkpath : "");
- fputs (line_buf, file);
- } else {
- if (!full) {
- fputs (cbuf, file);
- fputs ("\n", file);
- } else {
- fprintf (file, "%-37.37s", cbuf);
- fputs ((n & 1) ? " " : "\n", file);
- }
- }
- }
-
-
- #else /* MSDOS */
-
-
- static void
- format_fname_full (FILE *file, struct ffblk *sbuf, int full, int n, const char *path)
- {
- char line_buf[80]; /* for long dirlist */
- char cbuf[20]; /* for making line_buf */
- char which;
-
- strncpy (cbuf, sbuf->ff_name, 20);
- if (sbuf->ff_attrib & FA_DIREC)
- strcat (cbuf, "/");
- if (full == 1) {
- /* Long form, give other info too */
- sprintf (line_buf, "%-13s", cbuf);
- if (sbuf->ff_attrib & FA_DIREC)
- strcat (line_buf, " "); /* 11 spaces */
- else {
- sprintf (cbuf, "%ld", sbuf->ff_fsize);
- commas (cbuf);
- sprintf (line_buf + strlen (line_buf), "%10s ", cbuf);
- }
- sprintf (line_buf + strlen (line_buf), "%2d:%02d %2d/%02d/%02d%s",
- (sbuf->ff_ftime >> 11) & 0x1f, /* hour */
- (sbuf->ff_ftime >> 5) & 0x3f, /* minute */
- (sbuf->ff_fdate >> 5) & 0xf, /* month */
- (sbuf->ff_fdate) & 0x1f, /* day */
- (sbuf->ff_fdate >> 9) + 80, /* year */
- (full == 2) ? " | \n" : (n & 1) ? " " : "\n");
- fputs (line_buf, file);
- } else if (full == 2) {
- if (sbuf->ff_attrib & FA_DIREC)
- cbuf[strlen (cbuf) - 1] = 0; /* strip off the '/' */
- which = (sbuf->ff_attrib & FA_RDONLY) ? '-' : 'w';
- sprintf (line_buf, "%cr%c-r%c-r%c- 1 tnos tnos %8ld %3.3s %2d %2d:%02d %s\n",
- (sbuf->ff_attrib & FA_DIREC) ? 'd' : '-', which, which, which,
- sbuf->ff_fsize,
- Months[(sbuf->ff_fdate >> 5) & 0xf],
- (sbuf->ff_fdate) & 0x1f, /* day */
- (sbuf->ff_ftime >> 11) & 0x1f, /* hour */
- (sbuf->ff_ftime >> 5) & 0x3f, /* minute */
- cbuf);
- fputs (line_buf, file);
- } else {
- if (!full) {
- fputs (cbuf, file);
- fputs ("\n", file);
- } else {
- fprintf (file, "%-37.37s", cbuf);
- fputs ((n & 1) ? " " : "\n", file);
- }
- }
- }
- #endif
-
-
-
- /* Provide additional information only on DIR */
- static void
- print_free_space (const char *path, FILE *file, int n)
- {
- unsigned long free_bytes, total_bytes;
- char s_free[20], s_total[20];
- char cbuf[20];
- #ifdef UNIX
- char *pbuf;
- struct statfs vfsb;
- char *cp;
-
- pbuf = mallocw (1024);
- strncpy (pbuf, path, 1024 - 2);
- if ((cp = strrchr (pbuf, '/')) == 0)
- strcat (pbuf, "/.");
- else {
- *++cp = '.';
- *++cp = '\0';
- }
- #if defined(HAVE_SYS_STATFS_H) && !defined(linux)
- statfs (pbuf, &vfsb, sizeof vfsb, 0);
- #else
- (void) statfs (pbuf, &vfsb);
- #endif
- free_bytes = (unsigned long) (vfsb.f_bsize * vfsb.f_bavail);
- total_bytes = (unsigned long) (vfsb.f_bsize * vfsb.f_blocks);
- #else /* MSDOS or TNOS_68K */
- struct dfree dtable;
- unsigned long bpcl;
-
- #ifdef MSDOS
- int drive;
-
- if (path[1] == ':')
- drive = toupper(path[0]) - '@';
- else
- drive = 0;
- #endif
- /* Find disk free space */
- #ifndef TNOS_68K
- getdfree (uchar(drive), &dtable);
- #else
- getdfree (path, &dtable);
- #endif
-
- bpcl = dtable.df_bsec * dtable.df_sclus;
- free_bytes = dtable.df_avail * bpcl;
- total_bytes = dtable.df_total * bpcl;
- #endif
-
- if (n & 1)
- fputs ("\n", file);
-
- sprintf (s_free, "%ld", free_bytes);
- commas (s_free);
- sprintf (s_total, "%ld", total_bytes);
- commas (s_total);
-
- if (n)
- sprintf (cbuf, "%d", n);
- else
- strcpy (cbuf, "No");
-
- fprintf (file, "%s file%s. %s bytes free. Disk size %s bytes.\n",
- cbuf, (n == 1 ? "" : "s"), s_free, s_total);
- }
-
-
-
- static void
- free_clist (struct dirsort *this)
- {
- struct dirsort *next;
-
- while (this != NULLSORT) {
- next = this->next;
- free (this);
- this = next;
- }
- }
-
-
-
- /* Translate those %$#@!! backslashes to proper form */
- void
- undosify (char *s)
- {
- if (s) {
- while (*s != '\0') {
- if (*s == '\\')
- *s = '/';
- s++;
- }
- }
- }
-
-
-
- char *
- make_dir_path (int count, char *arg, const char *curdir)
- {
- char *tmpdir, *retval;
- char path[1024], *q;
-
- undosify (arg);
- tmpdir = strdup (curdir);
- undosify (tmpdir);
- if (count >= 2) {
- q = arg;
- q += strlen (arg) - 1;
- #ifndef TNOS_68K
- if (*q == '/' || *q == ':')
- #else
- if (*q == '/')
- #endif
- {
- strncpy (path, arg, 1024 - strlen (ALLFILES));
- strcat (path, ALLFILES);
- } else
- strncpy (path, arg, 1024);
- } else
- strncpy (path, ALLFILES, 1024);
-
- retval = make_fname (tmpdir, path);
- free (tmpdir);
- return (retval);
- }
-
-
-
- char *
- make_fname (const char *curdir, const char *fname0)
- {
- char *p, *fname;
- static char new_name[1024];
-
- strncpy (new_name, curdir, 1024);
- fname = strdup (fname0);
- if (fname)
- undosify (fname);
- if (fname && *fname) {
- if (*fname == '.') {
- if (*++fname == '/')
- fname++;
- else if (*fname == '.') {
- p = strrchr (new_name, '/');
- if (p)
- *p = 0;
- if (*++fname == '/')
- fname++;
- }
- }
- #ifdef MSDOS
- if (fname[0] == '/' || (strchr (fname, ':') != NULLCHAR))
- #else
- if (fname[0] == '/')
- #endif
- return fname;
- else {
- p = new_name;
- p += strlen (p) - 1;
- if (*p == '/')
- *p = '\0';
- crunch (new_name, fname);
- #ifdef MSDOS
- if (new_name[strlen (new_name) - 1] == ':')
- strcat (new_name, "/");
- #endif
- }
- }
- return new_name;
- }
-
-
-
- /* Check Drive/Directory for validity - 1=OK, 0=NOGOOD */
- int
- dir_ok (char *newpath, struct cur_dirs *dirs)
- {
- int result;
- char fullpath[1024];
- #ifdef TNOS_68K
- int new = 0;
-
- undosify (newpath);
- strlwr (newpath);
- result = ((access (newpath, S_IFDIR) == -1) ? 0 : 1);
- if (result) {
- /* chdir (newpath); */
- new = (*newpath == '/');
- sprintf (fullpath, "%s%s%s", !new ? dirs->dir : "", !new ? "/" : "", newpath);
- free (dirs->dir);
- dirs->dir = strdup (fullpath);
- }
- return (result);
- #else /* either MSDOS or UNIX */
- char curpath[1024];
- char buf[128];
-
- #ifdef MSDOS
- int drive = dirs->drv;
- #endif
- struct stat sbuf;
-
-
- undosify (newpath);
- strncpy (buf, newpath, 128);
- strncpy (curpath, dirs->dir, 1024);
-
- #ifdef MSDOS
- if (buf[1] == ':') {
- strncpy (fullpath, buf, 1024);
- } else
- #endif
- {
- if (*buf != '/')
- crunch (curpath, buf);
- else
- strncpy (curpath, buf + 1, 1024);
-
- #ifdef UNIX
- sprintf (fullpath, "%s%s", (*curpath != '/' ? "/" : ""), curpath);
- #else
- strncpy (fullpath, curpath, 1024);
- #endif
- }
-
- if (stat (fullpath, &sbuf) == -1 || !S_ISDIR (sbuf.st_mode))
- result = 0;
- else if ((result = access (fullpath, 0) + 1) == 1) {
- #ifdef UNIX
- free (dirs->dir);
- dirs->dir = strdup (fullpath);
- #else
- if (dirs->curdir[drive])
- free (dirs->curdir[drive]);
- dirs->curdir[drive] = strdup (fullpath);
- dirs->drv = drive;
- dirs->dir = dirs->curdir[drive];
- #endif
- }
- return result;
- #endif
- }
-
-
-
- const char *
- init_dirs (struct cur_dirs *dirs)
- {
- #ifdef UNIX
- dirs->dir = strdup (getcwd (NULL, 1024));
- return dirs->dir;
- #endif
- #ifdef TNOS_68K
- char fullpath[1024];
-
- dirs->dir = strdup (getcwd (fullpath, 1024));
- return (dirs->dir);
- #endif
- #ifdef MSDOS
- char buf[128], fullpath[128];
- int x, drive;
-
- for (x = 0; x <= 26; x++)
- dirs->curdir[x] = 0;
-
- drive = getdisk () + 1;
- (void) getcwd (buf, 128);
- undosify (buf);
- (void) strlwr (buf);
- sprintf (fullpath, "%c:/%s", drive + '`', &buf[3]);
- dirs->curdir[drive] = strdup (fullpath);
- dirs->drv = drive;
- dirs->dir = dirs->curdir[drive];
- return dirs->curdir[drive];
- #endif
- }
-
-
-
- void
- free_dirs (struct cur_dirs *dirs)
- {
- #ifdef UNIX
- free (dirs->dir);
- #else
- #ifdef TNOS_68K
- free (dirs->dir);
- #else
- int x;
-
- for (x = 0; x <= 26; x++) {
- if (dirs->curdir[x])
- free (dirs->curdir[x]);
- }
- #endif
- #endif
- }
-